package com.example.demolib.controller;


import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.example.demolib.entity.BookInfo;
import com.example.demolib.entity.PageRequest;
import com.example.demolib.entity.Result;
import com.example.demolib.entity.UserInfo;
import com.example.demolib.service.BookService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.rmi.server.RemoteRef;
import java.util.List;

/*
        解释三层架构-表现层（controller）、业务逻辑层（service）、数据操作层（dao）
        表现层；请求处理-对前端传过来的参数（形参）进行基本处理，响应数据（return语句）
        业务逻辑层：负责业务逻辑处理的代码
        数据操作层：负责业务数据的维护操作，包括增、删、改、查等操作.
        实体类（entity）
 */

@Slf4j
@RequestMapping("/book")
@RestController
public class BookController {

    @Autowired
    private BookService bookService;

    /**
     *
     * @param session
     * @param response
     * @throws IOException
     *
     *   使用HUtool工具生成验证码
     */
    @RequestMapping("/captcha")
    public void captcha(HttpSession session, HttpServletResponse response) throws IOException {

        // 生成验证码（宽100，高40，4位字符，50条干扰线）
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(100, 40, 4, 50);
        // 清除缓存-老版本
        response.setHeader("Pragma", "No-cache");
        // 清除缓存-旧版本
        response.setHeader("Cache-Control", "no-cache");
        // 设置格式为图片
        response.setContentType("image/png");

        // 将验证码和生成验证码时间存入session
        Long date = System.currentTimeMillis();
        session.setAttribute("captcha", captcha.getCode());
        session.setAttribute("date", date);

        // 输出验证码图片到浏览器
        captcha.write(response.getOutputStream());

        // 关闭输出流
        response.getOutputStream().close();
    }


    /**
     *      校验验证码、用户名、密码
     */
    @RequestMapping("/login")
    public Result<Object> login(String username, String password, String inputCaptcha, HttpSession session ) {
        log.info("username:{},password:{},inputCaptcha:{}",username,password,inputCaptcha);
        // 1. 校验验证码和验证码是否过期
        if(inputCaptcha==null){
            return Result.fail("验证码为空");
        }
        String sessionCaptcha = (String) session.getAttribute("captcha");
        if (!inputCaptcha.equalsIgnoreCase(sessionCaptcha) ||
                (System.currentTimeMillis() - (Long) session.getAttribute("date")) > 60000) {
            return Result.fail("验证码错误或已过期");
        }
        // 2.前端输入账号或密码为空
        if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return Result.fail("用户名或密码为空");
        }
        List<UserInfo> list = bookService.queryUserInfo();
        // 3.数据库返回结果为空
        if(list == null || list.size() == 0) {
            return Result.fail("系统错误");
        }
        // 4.匹配成功
        for(UserInfo userInfo : list) {
            if(username.equals(userInfo.getUserName())
                    && password.equals(userInfo.getPassword())) {
                // 保存登录标记到session
                session.setAttribute("loginUser", username);
                return Result.success(true);
            }
        }
        // 5.前端输入与数据库数据不匹配
        return Result.fail("用户名或密码错误");
    }

    /*
            退出登录，清除session中的loginUser信息
     */
    @RequestMapping("/logout")
    public Result<Object> logout(HttpSession session) {
        session.removeAttribute("loginUser");
        return Result.success(true);
    }


    /**
     *     此方法用来校验前端传过来的参数是否有效
     *     我们规定添加图书信息时，要求所有信息都不能为null
     */
    private boolean verifyInformation(BookInfo bookInfo) {
        if(bookInfo==null
                || bookInfo.getBookName()==null
                || bookInfo.getAuthor()==null
                || bookInfo.getCount()==null
                || bookInfo.getPrice()==null
                || bookInfo.getPublish()==null
                || bookInfo.getStatus()==null) {
            return false;
        }
        return true;
    }


    /**
     *      添加图书
     */
    @RequestMapping("/addBook")
    public Result<Object> addBook(BookInfo bookInfo) {
        log.info("addBook:{}",bookInfo);
        if(!verifyInformation(bookInfo)){
            return Result.fail("前端输入有误");
        }
        // 操作数据库
        Integer result = bookService.addBook(bookInfo);
        if(result==1) {
            // 数据库成功添加信息会返回1
            return Result.success(true);
        }else{
            return Result.fail("系统错误");
        }

    }


    /**
     *      展示图书列表
     */
    @RequestMapping("/getListByPage")
    public Result<PageRequest<BookInfo>> getListByPage(Integer currentPage,Integer pageSize) {
        log.info("getListByPage:{},{}",currentPage,pageSize);
        // 参数校验
        if(currentPage==null||pageSize==null) {
            // 如果前端没有传递参数，则为currentPage和pageSize给默认值
            currentPage=1;
            pageSize=10;
        }
        if(currentPage < 1) {
            // 前端传过来的页码小于1，显然不满足要求
            return Result.fail("前端输入有误前端输入有误");
        }
         return Result.success(bookService.getListByPage(currentPage,pageSize));
    }


    /**
     *   根据id查询图书信息
     *
     */
    @RequestMapping("/selectBookById")
    public Result<BookInfo> selectBookById(Integer bookId) {
        log.info("selectBookById:{}",bookId);
        if(bookId==null||bookId <1) {
            return Result.fail("前端输入有误");
        }
        return Result.success(bookService.selectBookById(bookId));
    }

    /*
          更新图书信息
     */
    @RequestMapping("/updateBook")
    public Result<Object> updateBook(BookInfo bookInfo) {
        log.info("updateBook:{}",bookInfo);
        Integer result = bookService.updateBook(bookInfo);
        if(result==1) {
            return Result.success(true);
        }
        return Result.fail("系统错误");
    }


    /*
            根据id删除图书信息
            使用逻辑删除，设置status为0即可
     */

    @RequestMapping("/deleteBookById")
    public Result<Object> deleteBookById(Integer bookId) {
        log.info("deleteBookById:{}",bookId);
        if(bookId==null||bookId <1) {
           return Result.fail("前端输入有误");
        }
        Integer result = bookService.deleteBookById(bookId);
        if(result==1) {
            return Result.success(true);
        }
        return Result.fail("系统错误");
    }



    /*
            根据id实现批量删除
     */

    @RequestMapping("/batchDeleteBookById")
    public Result<Object> batchDeleteBookById(@RequestParam("ids") List<Integer> ids) {
        log.info("batchDeleteBookById:{}",ids);
        if(ids==null||"".equals(ids) ) {
            return Result.fail("前端输入有误");
        }
        Integer result = bookService.batchDeleteBookById(ids);
        if(result>=1) {
            return Result.success(true);
        }
        return Result.fail("系统错误");
    }
}
